<script setup lang="ts">
import { computed, onMounted, reactive } from "vue";
import type { RuleObject } from "ant-design-vue/es/form";
import { Form, Modal } from "ant-design-vue";
import { handleApi, handleForm } from "@/utils/alert.ts";
import { getUserWaybillTemplates } from "@/api/waybill.ts";
import { usePagination } from "@/utils/hooks.ts";
import { IPrinter, PrinterError, usePrinterStore } from '@/stores/printer'



export type Emits = {
  submit: [ FormState ];
  cancel: [];
}

export type FormState = {
  printer: string;
  template: number | null;
}

const props = defineProps<{ orders?: IOrder[] }>()

const { dataSource, fetch, params } = usePagination(getUserWaybillTemplates, handleApi)
const asTemplate = (tpl: any) => tpl as IUserWaybillTemplate
const { getPrinters } = usePrinterStore();
const printers = reactive<(IPrinter & { default: boolean })[]>([])

const selectedTemplate = computed(() => dataSource.value?.find(i => i.id === formState.template))

onMounted(async () => {
  printers.filter(() => false)
  const res = await getPrinters().catch(err => {
    if (err instanceof PrinterError) {
      Modal.confirm({
        title: '打印机连接异常',
        content: '无法连接到打印机, 可能是打印组件未正确安装, 是否前往下载?',
        onOk: () => {
          window.open('https://cloudprint.douyinec.com/davinci/index', '_blank')
        }
      })
    } else {
      handleApi(res)
    }
  })
  if (res && res.printers) {
    res.printers.forEach(p => {
      printers.push({ ...p, default: p.name === res.defaultPrinter })
    })
    formState.printer = printers.find(i => i.default)?.name || ''
  }
  params.value.pagesize = 100
  await fetch()
  const df = dataSource.value?.find(i => i.is_default === 1)
  formState.template = df?.id || null
})

const emit = defineEmits<Emits>()

const formState = reactive<FormState>({
  printer: '',
  template: null
})
const formRules = reactive<PartialRecord<FormState, RuleObject[]>>({
  printer: [
    { required: true, message: '请选择打印机' }
  ],
  template: [
    { required: true, message: '请选择快递单模板' },
    { 
      validator: (_rule, value) => {
        const selected = dataSource.value?.find(i => i.id === value)
        return new Promise((resolve, reject) => {
          if (selected && selected.quantity >= (props.orders?.length || 0)) {
            resolve()
          } else {
            reject(`订单面单余额不足 ${props.orders?.length || 0}`)
          }
        })
      }
    }
  ]
})
const { validate, validateInfos } = Form.useForm(formState, formRules)

const onSubmit = async () => {
  const res = await validate().catch(handleForm)
  if (res) emit('submit', res)
}

</script>

<template>
  <div class="w-full mt-10">
    <div class="space-y-2 py-8 px-4 text-lg">
      <div>第一步：安装打印组件 <a href=" https://u2-401.ecukwai.com/kos/nlav11586/printer/KuaishouPrint-Setup-2.1.1.9_v1.exe" target="_blank">点击下载</a></div>
      <div>第二步：启动打印组件</div>
      <div>第三步：配置以下打印参数，然后打单</div>
    </div>
    <AForm layout="horizontal"
           autocomplete="off"
           :label-col="{ span: 6 }"
           :wrapper-col="{ span: 16 }"
           :model="formState"
           @finish="onSubmit">
      <AFormItem label="打印机" v-bind="validateInfos.printer">
        <ASelect v-model:value="formState.printer">
          <ASelectOption v-for="printer of printers" :value="printer.name">{{ printer.name }}</ASelectOption>
        </ASelect>
      </AFormItem>

      <AFormItem label="快递单模板" v-bind="validateInfos.template">
        <ASelect v-model:value="formState.template">
          <ASelectOption v-for="tpl of dataSource" :value="tpl.id">{{ asTemplate(tpl).title }}</ASelectOption>
        </ASelect>

        <div class="text-gray-400 py-1">剩余面单数量: {{ selectedTemplate?.quantity || '-' }}, 使用面单数量: {{ props.orders?.length || '-' }}</div>
      </AFormItem>

      <AFormItem :wrapper-col="{ offset: 6, span: 16 }">
        <div class="space-x-2 flex justify-end">
          <AButton type="primary" html-type="submit">打单</AButton>
          <AButton danger @click="emit('cancel')">取消</AButton>
        </div>
      </AFormItem>
    </AForm>
  </div>
</template>